package cn.edu.tju.elm.service;

import cn.edu.tju.core.model.User;
import cn.edu.tju.core.security.service.UserService;
import cn.edu.tju.elm.exception.DataNotFoundException;
import cn.edu.tju.elm.exception.ForbiddenException;
import cn.edu.tju.elm.exception.MethodArgumentNotValidException;
import cn.edu.tju.elm.model.entity.*;
import cn.edu.tju.elm.repository.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

@Service
@RequiredArgsConstructor
public class OrderService {
    private final OrderRepository orderRepository;
    private final BusinessRepository businessRepository;
    private final DeliveryAddressRepository deliveryAddressRepository;
    private final OrderDetailetRepository orderDetailetRepository;
    private final CartRepository cartRepository;
    private final UserService userService;


    public Order addOrder(Order order) {
        LocalDateTime now = LocalDateTime.now();
        User nowUser = userService.getUserWithAuthorities();

        Business exBusiness = businessRepository.findById(order.getBusiness().getId())
                .orElseThrow(()-> new MethodArgumentNotValidException("请求参数非法：店铺不存在"));

        DeliveryAddress exDeliveryAddress = deliveryAddressRepository.findById(order.getDeliveryAddress().getId())
                .orElseThrow(()-> new MethodArgumentNotValidException("请求参数非法：地址不存在"));

        List<Cart> carts = cartRepository.findAllByCustomerAndBusiness(nowUser,exBusiness);

        BigDecimal total = BigDecimal.ZERO;
        for(Cart cart:carts){
            total = total.add(cart.getFood().getFoodPrice().multiply(BigDecimal.valueOf(cart.getQuantity())));
        }


        if(total.compareTo(exBusiness.getStartPrice()) < 0){  // 不满足起送价
            throw new MethodArgumentNotValidException("请求参数非法：无法满足起送价");
        }

        Order newOrder = orderRepository.save(
                Order.builder()
                        .orderTotal(total.add(exBusiness.getDeliveryPrice())) // 加上配送费
                        .orderDate(now)
                        .business(exBusiness)
                        .orderState(0) // 0待支付
                        .customer(nowUser)
                        .deliveryAddress(exDeliveryAddress)

                        .createTime(now)
                        .updateTime(now)
                        .creator(nowUser.getId())
                        .updater(nowUser.getId())
                        .deleted(false)

                        .build());
        for(Cart cart:carts){
            OrderDetailet orderDetailet = OrderDetailet.builder()
                    .order(newOrder)
                    .food(cart.getFood())
                    .quantity(cart.getQuantity())

                    .createTime(now)
                    .updateTime(now)
                    .creator(nowUser.getId())
                    .updater(nowUser.getId())
                    .deleted(false)

                    .build();

            orderDetailetRepository.save(orderDetailet);
            cartRepository.delete(cart);
        }

        return newOrder;
    }

    public Order getOrderById(Long id) {
        User nowUser = userService.getUserWithAuthorities();
        Order existingOrder = orderRepository.findById(id)
                .orElseThrow(() -> new DataNotFoundException("资源未找到：订单不存在"));

        if(!existingOrder.getCustomer().equals(nowUser)){
            throw new ForbiddenException("权限不足：仅可查询当前用户的订单记录");
        }
        return existingOrder;
    }

    public List<Order> listOrdersByUser() {
        User nowUser = userService.getUserWithAuthorities();
        return orderRepository.findAllByCustomer(nowUser);
    }

    public Order patchOrder(Order order) {
        User nowUser = userService.getUserWithAuthorities();
        Order existingOrder = orderRepository.findById(order.getId())
                .orElseThrow(() -> new MethodArgumentNotValidException("请求参数非法：订单不存在"));

        DeliveryAddress deliveryAddress = new DeliveryAddress();
        if(!(order.getDeliveryAddress() ==null)){
            deliveryAddress = deliveryAddressRepository.findById(order.getDeliveryAddress().getId())
                    .orElseThrow(() -> new MethodArgumentNotValidException("请求参数非法：地址不存在"));
        }

        if(!nowUser.equals(existingOrder.getCustomer())){
            throw new ForbiddenException("权限不足：仅可更改当前用户订单");
        }

        if(!(order.getOrderState() ==null)){
            existingOrder.setOrderState(order.getOrderState());
        }

        if(!(order.getDeliveryAddress() ==null)){
            existingOrder.setDeliveryAddress(deliveryAddress);
        }

        LocalDateTime now = LocalDateTime.now();
        existingOrder.setUpdateTime(now);
        existingOrder.setUpdater(nowUser.getId());

        return orderRepository.save(existingOrder);
    }
}
